﻿using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Web;

namespace FlyingCircusWebIS.Models
{
    public class VooDAO : IVooDAO
    {
        private IAeronaveDAO aeronaveDAO;
        private IAeroportoDAO aeroportoDAO;
        private IPessoaDAO pessoaDAO;

        public VooDAO()
        {
            aeronaveDAO = new AeronaveDAO();
            aeroportoDAO = new AeroportoDAO();
            pessoaDAO = new PessoaDAO();
        }



        public void Adicionar(Voo entidade)
        {
            string sqlAdicionar = "insert into Voo (IdVoo, NomeVoo, PrecoVoo, Lucro, DataCadastro, IdAeroportoPartida, DataPartida, IdAeroportoChegada, DataChegada, IdAeronave, AssentosComercializaveis, IdPessoaUsuario, VooPromocional, DescontoPromocao) " +
                "values (seqVoo.nextval, 'FCA' || LPAD(seqVoo.currval, 4, '0'), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            //configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlAdicionar;

            OleDbParameter pPrecoVoo = new OleDbParameter("PrecoVoo", OleDbType.Numeric);
            pPrecoVoo.Value = entidade.PrecoVoo;
            comando.Parameters.Add(pPrecoVoo);

            OleDbParameter pLucro = new OleDbParameter("Lucro", OleDbType.Numeric);
            pLucro.Value = entidade.Lucro;
            comando.Parameters.Add(pLucro);

            OleDbParameter pDataCadastro = new OleDbParameter("DataCadastro", OleDbType.Date);
            pDataCadastro.Value = entidade.DataCadastro;
            comando.Parameters.Add(pDataCadastro);

            OleDbParameter pIdAeroportoPartida = new OleDbParameter("IdAeroportoPartida", OleDbType.Integer);
            pIdAeroportoPartida.Value = entidade.IdAeroportoPartida;
            comando.Parameters.Add(pIdAeroportoPartida);

            OleDbParameter pDataPartida = new OleDbParameter("DataPartida", OleDbType.Date);
            pDataPartida.Value = entidade.DataPartida;
            comando.Parameters.Add(pDataPartida);

            OleDbParameter pIdAeroportoChegada = new OleDbParameter("IdAeroportoChegada", OleDbType.Integer);
            pIdAeroportoChegada.Value = entidade.IdAeroportoChegada;
            comando.Parameters.Add(pIdAeroportoChegada);

            OleDbParameter pDataChegada = new OleDbParameter("DataChegada", OleDbType.Date);
            pDataChegada.Value = entidade.DataChegada;
            comando.Parameters.Add(pDataChegada);

            OleDbParameter pIdAeronave = new OleDbParameter("IdAeronave", OleDbType.Integer);
            pIdAeronave.Value = entidade.IdAeronave;
            comando.Parameters.Add(pIdAeronave);

            OleDbParameter pAssentosComercializaveis = new OleDbParameter("AssentosComercializaveis", OleDbType.Integer);
            pAssentosComercializaveis.Value = entidade.AssentosComercializaveis;
            comando.Parameters.Add(pAssentosComercializaveis);

            OleDbParameter pIdPessoaUsuario = new OleDbParameter("IdPessoaUsuario", OleDbType.Integer);
            pIdPessoaUsuario.Value = entidade.IdPessoaUsuario;
            comando.Parameters.Add(pIdPessoaUsuario);

            OleDbParameter pVooPromocional = new OleDbParameter("VooPromocional", OleDbType.VarChar);
            pVooPromocional.Value = entidade.VooPromocional;
            comando.Parameters.Add(pVooPromocional);

            OleDbParameter pDescontoPromocao = new OleDbParameter("DescontoPromocao", OleDbType.Numeric);
            pDescontoPromocao.Value = entidade.DescontoPromocao;
            comando.Parameters.Add(pDescontoPromocao);

            //Insert
            comando.ExecuteNonQuery();
            comando.Dispose();

        }

        public void Atualizar(Voo entidade)
        {
            string sqlAtualizar = "update Voo set PrecoVoo = ?, Lucro = ?, DataCadastro = ?, IdAeroportoPartida = ?, DataPartida = ?, IdAeroportoChegada = ?, DataChegada = ?, IdAeronave = ?, AssentosComercializaveis = ?, IdPessoaUsuario = ?, VooPromocional = ?, DescontoPromocao = ? where IdVoo = ?";

            //configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlAtualizar;

            OleDbParameter pPrecoVoo = new OleDbParameter("PrecoVoo", OleDbType.Numeric);
            pPrecoVoo.Value = entidade.PrecoVoo;
            comando.Parameters.Add(pPrecoVoo);

            OleDbParameter pLucro = new OleDbParameter("Lucro", OleDbType.Numeric);
            pLucro.Value = entidade.Lucro;
            comando.Parameters.Add(pLucro);

            OleDbParameter pDataCadastro = new OleDbParameter("DataCadastro", OleDbType.Date);
            pDataCadastro.Value = entidade.DataCadastro;
            comando.Parameters.Add(pDataCadastro);

            OleDbParameter pIdAeroportoPartida = new OleDbParameter("IdAeroportoPartida", OleDbType.Integer);
            pIdAeroportoPartida.Value = entidade.IdAeroportoPartida;
            comando.Parameters.Add(pIdAeroportoPartida);

            OleDbParameter pDataPartida = new OleDbParameter("DataPartida", OleDbType.Date);
            pDataPartida.Value = entidade.DataPartida;
            comando.Parameters.Add(pDataPartida);

            OleDbParameter pIdAeroportoChegada = new OleDbParameter("IdAeroportoChegada", OleDbType.Integer);
            pIdAeroportoChegada.Value = entidade.IdAeroportoChegada;
            comando.Parameters.Add(pIdAeroportoChegada);

            OleDbParameter pDataChegada = new OleDbParameter("DataChegada", OleDbType.Date);
            pDataChegada.Value = entidade.DataChegada;
            comando.Parameters.Add(pDataChegada);

            OleDbParameter pIdAeronave = new OleDbParameter("IdAeronave", OleDbType.Integer);
            pIdAeronave.Value = entidade.IdAeronave;
            comando.Parameters.Add(pIdAeronave);

            OleDbParameter pAssentosComercializaveis = new OleDbParameter("AssentosComercializaveis", OleDbType.Integer);
            pAssentosComercializaveis.Value = entidade.AssentosComercializaveis;
            comando.Parameters.Add(pAssentosComercializaveis);

            OleDbParameter pIdPessoaUsuario = new OleDbParameter("IdPessoaUsuario", OleDbType.Integer);
            pIdPessoaUsuario.Value = entidade.IdPessoaUsuario;
            comando.Parameters.Add(pIdPessoaUsuario);

            OleDbParameter pVooPromocional = new OleDbParameter("VooPromocional", OleDbType.VarChar);
            pVooPromocional.Value = entidade.VooPromocional;
            comando.Parameters.Add(pVooPromocional);

            OleDbParameter pDescontoPromocao = new OleDbParameter("DescontoPromocao", OleDbType.Numeric);
            pDescontoPromocao.Value = entidade.DescontoPromocao;
            comando.Parameters.Add(pDescontoPromocao);

            OleDbParameter pIdVoo = new OleDbParameter("IdVoo", OleDbType.Integer);
            pIdVoo.Value = entidade.IdVoo;
            comando.Parameters.Add(pIdVoo);

            //Update
            comando.ExecuteNonQuery();
            comando.Dispose();
        }

        public void RemoverPorId(int id)
        {
            string sqlDeletar = "delete Voo where IdVoo = ?";

            // Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlDeletar;

            OleDbParameter pId = new OleDbParameter("IdVoo", OleDbType.VarChar);
            pId.Value = id;
            comando.Parameters.Add(pId);

            // Delete
            comando.ExecuteNonQuery();
            comando.Dispose();
        }

        public Voo BuscarPorId(int id)
        {
            Voo registro = null;
            string sqlBuscar = "select * from Voo where IdVoo = ?";

            //Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlBuscar;

            OleDbParameter pId = new OleDbParameter("IdVoo", OleDbType.Integer);
            pId.Value = id;
            comando.Parameters.Add(pId);

            //Select
            OleDbDataReader dr = comando.ExecuteReader();
            while (dr.Read())
            {
                registro = ConverterDataReaderParaObj(dr);
            }
            dr.Close();
            comando.Dispose();

            if (registro != null)
                CarregarComposicao(registro);

            return registro;
        }

        private Voo ConverterDataReaderParaObj(OleDbDataReader dr)
        {
            Voo registro = new Voo();
            registro.IdVoo = Int32.Parse(dr["IdVoo"].ToString());
            registro.NomeVoo = dr["NomeVoo"].ToString();
            registro.PrecoVoo = Decimal.Parse(dr["PrecoVoo"].ToString());
            registro.Lucro = Decimal.Parse(dr["Lucro"].ToString());
            registro.DataCadastro = DateTime.Parse(dr["DataCadastro"].ToString());
            registro.IdAeroportoPartida = Int32.Parse(dr["IdAeroportoPartida"].ToString());
            registro.DataPartida = DateTime.Parse(dr["DataPartida"].ToString());
            registro.IdAeroportoChegada = Int32.Parse(dr["IdAeroportoChegada"].ToString());
            registro.DataChegada = DateTime.Parse(dr["DataChegada"].ToString());
            registro.IdAeronave = Int32.Parse(dr["IdAeronave"].ToString());
            registro.AssentosComercializaveis = Int32.Parse(dr["AssentosComercializaveis"].ToString());
            registro.IdPessoaUsuario = Int32.Parse(dr["IdPessoaUsuario"].ToString());
            registro.VooPromocional = dr["VooPromocional"].ToString();
            registro.DescontoPromocao = Decimal.Parse(dr["DescontoPromocao"].ToString());

            return registro;
        }


        public List<Voo> Listar()
        {
            String sqlConsulta = "select * from Voo";

            //Configura o comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlConsulta;

            // Select
            OleDbDataReader dr = comando.ExecuteReader();

            List<Voo> registros = new List<Voo>();
            while (dr.Read())
            {
                Voo registro = ConverterDataReaderParaObj(dr);
                registros.Add(registro);
            }
            dr.Close();
            comando.Dispose();

            foreach (var registro in registros)
            {
                CarregarComposicao(registro);
            }

            return registros;

        }

        private void CarregarComposicao(Voo voo)
        {
            int idAeronave = voo.IdAeronave;
            Aeronave aeronave = aeronaveDAO.BuscarPorId(idAeronave);
            voo.Aeronave = aeronave;

            int idAeroportoPartida = voo.IdAeroportoPartida;
            Aeroporto aeroportoPartida = aeroportoDAO.BuscarPorId(idAeroportoPartida);
            voo.AeroportoPartida = aeroportoPartida;

            int idAeroportoChegada = voo.IdAeroportoChegada;
            Aeroporto aeroportoChegada = aeroportoDAO.BuscarPorId(idAeroportoChegada);
            voo.AeroportoChegada = aeroportoChegada;

            int idPessoaUsuario = voo.IdPessoaUsuario;
            Pessoa pessoaUsuario = pessoaDAO.BuscarPorId(idPessoaUsuario);
            voo.PessoaUsuario = pessoaUsuario;
        }

        public List<VooFormatado> ListarVooFormatado()
        {
            String sqlConsulta = "select * from VooFormatado order by DataPartida";

            //Configura comando
            OleDbCommand comando = new OleDbCommand();
            comando.Connection = GerenciadorConexao.Conexao;
            comando.CommandText = sqlConsulta;

            //select
            OleDbDataReader dr = comando.ExecuteReader();

            List<VooFormatado> registros = new List<VooFormatado>();
            while (dr.Read())
            {
                VooFormatado registro = new VooFormatado();

                registro.NomeVoo = dr["NomeVoo"].ToString();
                registro.DataPartida = DateTime.Parse(dr["DataPartida"].ToString());
                registro.IdAeroportoPartida = Int32.Parse(dr["IdAeroportoPartida"].ToString());
                registro.NomeAeroportoPartida = dr["NomeAeroportoPartida"].ToString();
                registro.NomeCidadePartida = dr["NomeCidadePartida"].ToString();
                registro.UFPartida = dr["UFPartida"].ToString();
                registro.IdAeroportoChegada = Int32.Parse(dr["IdAeroportoChegada"].ToString());
                registro.DataChegada = DateTime.Parse(dr["DataChegada"].ToString());
                registro.NomeAeroportoChegada = dr["NomeAeroportoChegada"].ToString();
                registro.NomeCidadeChegada = dr["NomeCidadeChegada"].ToString();
                registro.UFChegada = dr["UFChegada"].ToString();
                registro.PaisChegada = dr["PaisChegada"].ToString();
                registro.IdVoo = Int32.Parse(dr["IdVoo"].ToString());
                registro.IdAeronave = Int32.Parse(dr["IdAeronave"].ToString());
                registro.AssentosComercializaveis = Int32.Parse(dr["AssentosComercializaveis"].ToString());
                registro.PrecoVoo = Decimal.Parse(dr["PrecoVoo"].ToString());
                registro.Lucro = double.Parse(dr["Lucro"].ToString());
                registro.VooPromocional = dr["VooPromocional"].ToString();
                registro.DescontoPromocao = double.Parse(dr["DescontoPromocao"].ToString());
                registro.IdPessoaUsuario = Int32.Parse(dr["IdPessoaUsuario"].ToString());
                registro.DataCadastro = DateTime.Parse(dr["DataCadastro"].ToString());

                registros.Add(registro);
            }
            dr.Close();
            comando.Dispose();

            return registros;
        }

        public List<Aeronave> ListarAeronavesDisponiveis(DateTime dataPartida, DateTime dataChegada)
        {
            string sqlBuscarAeronaves = "select distinct ae.IdAeronave, ma.IdModeloAeronave, ae.Descricao, ae.FlagAtivo " +
                                        "from Aeronave ae, Voo vo, ModeloAeronave ma " +
                                        "where vo.IdAeronave(+) = ae.IdAeronave " +
                                        "and ma.IdModeloAeronave = ae.IdModeloAeronave " +
                                        "minus " +
                                        "select distinct vo.IdAeronave, ma.IdModeloAeronave, ae.Descricao, ae.FlagAtivo " +
                                        "from Aeronave ae, Voo vo, ModeloAeronave ma " +
                                        "where ae.IdAeronave = vo.IdAeronave " +
                                        "and ma.IdModeloAeronave = ae.IdModeloAeronave " +
                                        "and (vo.DataPartida between TO_DATE('" + dataPartida.ToString() + "', 'dd/mm/yyyy hh24:mi:ss') - 5/24 and TO_DATE('" + dataChegada.ToString() + "', 'dd/mm/yyyy hh24:mi:ss')+5/24) " +
                                        "or vo.DataChegada between TO_DATE('" + dataPartida.ToString() + "', 'dd/mm/yyyy hh24:mi:ss')- 5/24 and TO_DATE('" + dataChegada.ToString() + "', 'dd/mm/yyyy hh24:mi:ss') + 5/24 " +
                                        "or (vo.DataPartida < TO_DATE('" + dataPartida.ToString() + "', 'dd/mm/yyyy hh24:mi:ss')- 5/24 and vo.DataChegada > (TO_DATE('" + dataChegada.ToString() + "', 'dd/mm/yyyy hh24:mi:ss')+5/24))";

            OleDbCommand comando = new OleDbCommand();
            comando.CommandText = sqlBuscarAeronaves;
            comando.Connection = GerenciadorConexao.Conexao;

            //select
            OleDbDataReader dr = comando.ExecuteReader();

            List<Aeronave> registros = new List<Aeronave>();
            while (dr.Read())
            {
                Aeronave registro = ConverterDataReaderAeronavesParaObj(dr);
                registros.Add(registro);
            }
            dr.Close();
            comando.Dispose();

            return registros;
        }

        private Aeronave ConverterDataReaderAeronavesParaObj(OleDbDataReader dr)
        {
            Aeronave registro = new Aeronave();
            registro.IdAeronave = Int32.Parse(dr["IdAeronave"].ToString());
            registro.IdModeloAeronave = Int32.Parse(dr["IdModeloAeronave"].ToString());
            registro.Descricao = dr["Descricao"].ToString();
            registro.FlagAtivo = dr["FlagAtivo"].ToString();

            return registro;
        }

    }
}